-
Notifications
You must be signed in to change notification settings - Fork 9.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent unset Boolean product attributes from displaying in product page #10619
Conversation
Thanks, that's exactly what I was suggesting in https://github.com/magento/magento2/pull/8623/files#r102056203. What do you think about writing a unit test? It's enough to cover just the case you fixed when |
@orlangur I have added a test class with two test cases for when a custom attribute of class Phrase is used, but I also modified the proposed fix to change the line: |
Thanks! I see |
Nice catch with
As you see here, in case of |
@orlangur I just changed the ordering of the ifelse checks to place the "instanceof Phrase" check before the "(string) $value" check, so if it is a Phrase it will not be cast to a string for one check and then again rendered in a later check. Does this satisfy the improvement you had in mind? |
@usesi-jlambert yeah, should render only once now.
What do you think about making it
? It will call |
@orlangur Updated with the latest suggestion, can you perform a "squash and merge" through Github or do I need to rebase it in my own repo? |
This should be done in your branch and force-pushed as otherwise PR will not be marked as Merged. But please check unit test is still working under PHPUnit 6 locally first. |
10d62c1
to
d907f6c
Compare
@orlangur Commits merged and updated in the pull request |
@usesi-jlambert sorry, I forgot to write a comment regarding static test failing. Would you mind to fix it (and amend commit, as always)? |
/** | ||
* Test class for \Magento\Catalog\Block\Product\View\Attributes | ||
* | ||
* @SuppressWarnings(PHPMD.LongVariable) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please get rid of this. priceCurrencyInterfaceMock
could be names simply priceCurrency
(everything besides test object is a mock in unit test).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ping @usesi-jlambert :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mock has been removed from all variable names.
*/ | ||
class AttributesTest extends TestCase | ||
{ | ||
const TESTATTRIBUTENAME = 'phrase'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please use underscore as word separator: TEST_ATTRIBUTE_NAME
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed Constants and used strings where necessary to remove the Phrase class complaint.
*/ | ||
private $attributesBlock; | ||
|
||
protected function setUp() // @codingStandardsIgnoreLine |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PHPCS errors suppression must be avoided. Please get rid of all such ignores.
Use real strings instead of constants or replace real Phrase
object with a mock.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
->method('getFrontend') | ||
->willReturn($this->frontendAttributeMock); | ||
|
||
$this->productMock = $this |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not insist on changing all mocks creation this time, but generally createMock
with all statements in one line would be much faster to read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lines not exceeding 120 characters are per the MEQP2 standard available here:
https://github.com/magento/marketplace-eqp
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I don't understand this comment.
Yeah, 120 characters limit should be honored, just there is no need to break the line for each method call, it could be:
$mock->expects()->method()
->willReturn()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I structured it this way to avoid exceeding line length, but I also find it easier to read with a method on each line so I can read it like a checklist of items that are completed to get the final result. I can refactor if it is a big deal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It more a matter of taste, as I said, there is no strict requirement regarding this. Please leave as is.
|
||
$attributes = $this->attributesBlock->getAdditionalData(); | ||
|
||
$this::assertTrue(empty($attributes[self::TESTATTRIBUTENAME])); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace all static calls with $this->assert*
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I modified these to static because I was receiving a warning for calling a static method dynamically, but it works regardless of which way they are called so I will swap them back.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Warning in IDE? Surely it works, just that it is used as $this->assert*
in most of the tests (~200 VS ~8000 occurrences).
Just found out that $this->
is a recommended by PHPUnit author way: sebastianbergmann/phpunit#1922, https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.static-vs-non-static-usage-of-assertion-methods
Please eliminate these static calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They have been swapped back in the latest commit
/** | ||
* Test class for \Magento\Catalog\Block\Product\View\Attributes | ||
* | ||
* @SuppressWarnings(PHPMD.LongVariable) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ping @usesi-jlambert :)
protected function setUp() | ||
{ | ||
$this->phrase = new Phrase( | ||
'' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we have each new Phrase
on a single line?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@orlangur Any thoughts on why the travic-ci build is failing now? I'm at a bit of a loss on that error. |
@usesi-jlambert this failure is Travis-specific, simply ignore it, I'll run against internal CI. Please remove the |
@usesi-jlambert please amend all changes into one commit, besides that looks good to me, great job 👍 |
Small remark: what is the point of creating the Phrases |
Are you saying that with |
@orlangur: indeed, a Phrase passes |
@hostep I see... I believe previous PR was exactly about fixing this case and we want to see I'm inclined to change last condition to |
The problem where we are running into, is that we don't want to see This PR by @usesi-jlambert happens to (accidentally?) fix #9961, but the code is really confusing right now as you can imagine :) Or should the behavior of displaying |
@hostep,
The fact such attributes with |
Per the discussion here: magento#6634 I found when I implemented the proposed fix that was implemented in this file in my own Magento installation, all boolean attributes were returned even if they were not assigned to a product and had no value in the database. So my product pages were full of NULLs and had a large number of non-relevant attributes listed because of the large number of custom attributes we are utilizing for our product catalog. The small change I have made here allows attributes that have been assigned a value to be displayed, but non-relevant/unset attributes are not, therefore I feel it is a much cleaner solution to the problem.
@usesi-jlambert: this is an incorrect statement, because you removed So this means the The question is: is this the correct behaviour or not, do we want to see |
@hostep As for which is the preferred behavior, I created this pull request because I ran into the problem of boolean attributes not displaying properly, and we have close to 50 custom boolean product attributes so that was a problem, but when I made the modification that was eventually merged into 2.1.7 I had a product page filled with useless information for attributes that had no values and no in built way to hide them. I found that the proposed alternate solution was much more desirable from my perspective, and when compared to the 2.1.6 release only changes the result to include information that was omitted before, while the 2.1.7 version's change introduced a large amount of useless information with no good method of hiding it on a product by product basis. If you wanted to force a product to show an attribute value of N/A when no value was set, then you could create a custom text attribute, and set the default value to N/A. So working around case by case issues, from my perspective, is easier with my version of the fix than it is with the current 2.1.7 fix. Thoughts? |
I agree @usesi-jlambert, I also want to go back to the state like it was in Magento 2.1.6. But, looking at the code, it seems like it was meant to display But I agree, and (some of) our clients as well, they also seem to want to go back to how it was in Magento 2.1.6. But then I think the code has to change a little bit, to make it less confusing, and I'd like to propose to change: @orlangur, or someone from the Magento devs, feedback would be appreciated! :) |
|
||
protected function setUp() | ||
{ | ||
$this->phrase = new Phrase(__('')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function __
returns a Phrase instance. Use new Phrase('')
or __('')
. Result will be the same. While your code is working it lead to static tests failure:
Magento\Test\Integrity\Phrase\ArgumentsTest::testArguments
2 missed phrases were discovered:
Missed Phrase: File: /opt/bamboo/bamboo-agent-home/xml-data/build-dir/M2-AT2646-INSE/magento2ce/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php
Line: 67
Missed Phrase: File: /opt/bamboo/bamboo-agent-home/xml-data/build-dir/M2-AT2646-INSE/magento2ce/app/code/Magento/Catalog/Test/Unit/Block/Product/View/AttributesTest.php
Line: 146
Failed asserting that an array is empty.
/opt/bamboo/bamboo-agent-home/xml-data/build-dir/M2-AT2646-INSE/magento2ce/dev/tests/static/testsuite/Magento/Test/Integrity/Phrase/ArgumentsTest.php:66
@@ -84,13 +84,15 @@ public function getAdditionalData(array $excludeAttr = []) | |||
|
|||
if (!$product->hasData($attribute->getAttributeCode())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this if
as this is dead code for a long time.
@@ -84,13 +84,15 @@ public function getAdditionalData(array $excludeAttr = []) | |||
|
|||
if (!$product->hasData($attribute->getAttributeCode())) { | |||
$value = __('N/A'); | |||
} elseif ($value instanceof Phrase) { | |||
$value = (string)$value; | |||
} elseif ((string)$value == '') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove this elseif
as converting an empty value to No
is pretty weird logic. If this is a workaround for some bug it should be fixed in another way as this code only hides the real problem.
Regarding @hostep comment
It won't have impact as then it was filtered out by |
@usesi-jlambert If you don't have time to work on this PR now, please allow edits from maintainers and I will finish and merge it. |
All required fixes applied in internal repo. PR will be merged soon. |
@vkublytskyi I have modified this PR to allow edits from maintainers. |
…ng in product page #10619
…ng in product page #10619
Description
Per the discussion here:
#6634
I found when I implemented the proposed fix that was implemented in this file in my own Magento installation, all boolean attributes were returned even if they were not assigned to a product and had no value in the database. So my product pages were full of NULLs and had a large number of non-relevant attributes listed because of the large number of custom attributes we are utilizing for our product catalog. The small change I have made here allows attributes that have been assigned a value to be displayed, but non-relevant/unset attributes are not, therefore I feel it is a much cleaner solution to the problem.
Fixed Issues (if relevant)
Manual testing scenarios
Before Fix:
After Fix:
Contribution checklist